//! 交易品种DTO
//!
//! 该模块定义了交易品种的相关数据结构和订阅结构体,
//! 包括该品种可进行的交易类型, 可进行的交易方向, 最小交易单位等
//!
//! 用于在回测或者撮合系统时查看的Meta信息
//!

use crate::Message;
use serde::{Deserialize, Serialize};
use std::hash::{Hash, Hasher};
use tokio::sync::mpsc;
use std::sync::Arc;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum DataType {
    Tick,
    Bar,
    Position,
    OrderDone,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum Frequency {
    Minute,
    Hourly,
    Daily,
    Weekly,
    Monthly,
}

/// 全局事件 - 紧凑设计，用于 SPMC 广播
#[derive(Debug)]
pub struct GlobalEvent {
    pub dtype: DataType,
    pub symbol: Option<String>,
    pub frequency: Option<Frequency>,
    
    // SPSC 通道 - 用于接收数据并广播给所有客户端
    sender: mpsc::UnboundedSender<Message>,
    receiver: Arc<tokio::sync::Mutex<mpsc::UnboundedReceiver<Message>>>,
}

impl Hash for GlobalEvent {
    fn hash<H: Hasher>(&self, state: &mut H) {
        // 只对 dtype, symbol, frequency 进行哈希
        // 忽略通道字段
        self.dtype.hash(state);
        self.symbol.hash(state);
        self.frequency.hash(state);
    }
}

impl PartialEq for GlobalEvent {
    fn eq(&self, other: &Self) -> bool {
        // 只比较 dtype, symbol, frequency
        // 忽略通道字段
        self.dtype == other.dtype
            && self.symbol == other.symbol
            && self.frequency == other.frequency
    }
}

impl Eq for GlobalEvent {}

impl Clone for GlobalEvent {
    fn clone(&self) -> Self {
        // 创建新的通道
        let (sender, receiver) = mpsc::unbounded_channel::<Message>();
        
        Self {
            dtype: self.dtype.clone(),
            symbol: self.symbol.clone(),
            frequency: self.frequency.clone(),
            sender,
            receiver: Arc::new(tokio::sync::Mutex::new(receiver)),
        }
    }
}

impl GlobalEvent {    
    /// 创建新的全局事件
    pub fn new(
        dtype: DataType,
        symbol: Option<String>,
        frequency: Option<Frequency>,
    ) -> Self {
        let (sender, receiver) = mpsc::unbounded_channel::<Message>();
        
        Self {
            dtype,
            symbol,
            frequency,
            sender,
            receiver: Arc::new(tokio::sync::Mutex::new(receiver)),
        }
    }
    
    /// 获取 Sender 的克隆
    /// 
    /// # Returns
    /// 返回可以发送消息的 Sender
    pub fn get_sender(&self) -> mpsc::UnboundedSender<Message> {
        self.sender.clone()
    }
    
    /// 获取 Receiver 的引用
    /// 
    /// # Returns
    /// 返回可以接收消息的 Receiver（包装在 Arc<Mutex> 中）
    pub fn get_receiver(&self) -> Arc<tokio::sync::Mutex<mpsc::UnboundedReceiver<Message>>> {
        Arc::clone(&self.receiver)
    }
    
    /// 发送消息到通道
    /// 
    /// # Arguments
    /// * `message` - 要发送的消息
    /// 
    /// # Returns
    /// 发送成功返回 Ok(())，失败返回错误
    pub fn send(&self, message: Message) -> Result<(), mpsc::error::SendError<Message>> {
        self.sender.send(message)
    }
}

#[derive(Debug)]
pub struct SubscribeEvent {
    pub dtype: DataType,              // 数据类型
    pub client_id: u64,               // 订阅用户ID
    pub symbol: Option<String>,       // 品种(特殊的品种是strat_id, 同场stage的参与策略净值, 包括自己, 如果是OrderDone/Position的事件则None)
    pub frequency: Option<Frequency>, // 数据频率(Tick/Event没有频率)
    
    // MPSC 通道
    sender: mpsc::UnboundedSender<Message>,
    receiver: Arc<tokio::sync::Mutex<mpsc::UnboundedReceiver<Message>>>,
}

impl Hash for SubscribeEvent {
    fn hash<H: Hasher>(&self, state: &mut H) {
        // 只对 client_id, symbol, dtype, frequency 进行哈希
        // 忽略 payload 字段
        self.client_id.hash(state);
        self.symbol.hash(state);
        self.dtype.hash(state);
        self.frequency.hash(state);
    }
}

impl PartialEq for SubscribeEvent {
    fn eq(&self, other: &Self) -> bool {
        // 只比较 client_id, symbol, dtype, frequency
        // 忽略 payload 字段
        self.client_id == other.client_id
            && self.symbol == other.symbol
            && self.dtype == other.dtype
            && self.frequency == other.frequency
    }
}

impl Eq for SubscribeEvent {}

impl SubscribeEvent {
    /// 创建新的订阅事件，自动创建 MPSC 通道
    /// 
    /// # Arguments
    /// * `dtype` - 数据类型
    /// * `client_id` - 订阅用户ID
    /// * `symbol` - 品种符号
    /// * `frequency` - 数据频率
    /// 
    /// # Returns
    /// 返回订阅事件实例
    pub fn new(
        dtype: DataType,
        client_id: u64,
        symbol: Option<String>,
        frequency: Option<Frequency>,
    ) -> Self {
        let (sender, receiver) = mpsc::unbounded_channel::<Message>();
        
        Self {
            dtype,
            client_id,
            symbol,
            frequency,
            sender,
            receiver: Arc::new(tokio::sync::Mutex::new(receiver)),
        }
    }
    
    /// 获取 Sender 的克隆
    /// 
    /// # Returns
    /// 返回可以发送消息的 Sender
    pub fn get_sender(&self) -> mpsc::UnboundedSender<Message> {
        self.sender.clone()
    }
    
    /// 获取 Receiver 的引用
    /// 
    /// # Returns
    /// 返回可以接收消息的 Receiver（包装在 Arc<Mutex> 中）
    pub fn get_receiver(&self) -> Arc<tokio::sync::Mutex<mpsc::UnboundedReceiver<Message>>> {
        Arc::clone(&self.receiver)
    }
    
    /// 发送消息到通道
    /// 
    /// # Arguments
    /// * `message` - 要发送的消息
    /// 
    /// # Returns
    /// 发送成功返回 Ok(())，失败返回错误
    pub fn send(&self, message: Message) -> Result<(), mpsc::error::SendError<Message>> {
        self.sender.send(message)
    }
}